import storage from './storage';
import formatDate from './formatDate';
import userRole from './userRole';
import ResultMessage from './ResultMessage';

/**
 * 根据给定的开始日期和结束日期生成日期数组
 * 
 * @param start 开始日期的字符串，格式为'yyyy-MM-dd'
 * @param end 结束日期的字符串，格式为'yyyy-MM-dd'
 * @returns 返回一个字符串数组，包含了从开始日期到结束日期的所有日期
 */
function generateDates(start: string | Date, end: string | Date, step: number = 1, format = 'yyyy-MM-dd'): string[] {
  // 将开始日期字符串转换为Date对象
  const startDate = new Date(start);
  // 将结束日期字符串转换为Date对象
  const endDate = new Date(end);
  // 初始化一个空数组，用于存储生成的日期字符串
  const dates: string[] = [];

  // 使用for循环从开始日期遍历到结束日期
  for (let currentDate = startDate; currentDate <= endDate; currentDate.setDate(currentDate.getDate() + step)) {
    // 将当前日期格式化为'yyyy-MM-dd'并添加到dates数组中
    dates.push(formatDate(currentDate, format));
  }

  // 返回生成的日期数组
  return dates;
}
function generateDates2(start: string | Date, end: string | Date, step: number = 1, format = 'yyyy-MM-dd'): string[] {
  // 将开始日期字符串转换为Date对象
  const startDate = new Date(start);
  // 将结束日期字符串转换为Date对象
  const endDate = new Date(end);
  // 初始化一个空数组，用于存储生成的日期字符串
  const dates: any[] = [];

  // 使用for循环从开始日期遍历到结束日期
  for (let currentDate = startDate; currentDate <= endDate; currentDate.setDate(currentDate.getDate() + step)) {
    // 将当前日期格式化为'yyyy-MM-dd'并添加到dates数组中
    dates.push({ date: formatDate(currentDate, format), week: currentDate.getDay() });
  }

  // 返回生成的日期数组
  return dates;
}
/**
 * 判断给定的日期是否在指定的开始日期和结束日期之间（包括边界）
 * 
 * @param start 开始日期的字符串，格式为'yyyy-MM-dd'
 * @param end 结束日期的字符串，格式为'yyyy-MM-dd'
 * @param dateToCheck 要检查的日期的字符串，格式为'yyyy-MM-dd'
 * @returns 返回一个布尔值，表示dateToCheck是否在start和end之间（包括边界）
 */
function isDateBetween(start: string | Date, end: string | Date, dateToCheck: string | Date): boolean {
  // 将日期字符串转换为Date对象
  const startDate = new Date(start);
  const endDate = new Date(end);
  const checkDate = new Date(dateToCheck);

  // 比较日期
  return checkDate >= startDate && checkDate <= endDate;
}

/**
 * 获取今天和前两周的日期数组
 *
 * @param now 当前日期
 * @returns 包含今天和前两周日期的数组
 */
const getTodayAndPreviousTwoWeeks = (now: Date) => {
  // 计算前两周的周一的日期（从当天回退14天，再加上(7 - 当天周几 + 1) % 7 天）
  const twoWeeksAgo = new Date(now.getTime() - 14 * 24 * 60 * 60 * 1000); // 回退14天
  // 加上偏移量得到前两周的周一

  return [now, twoWeeksAgo];
};

/**
 * 获取两个日期之间的所有完整周
 *
 * @param startDate 开始日期，默认为当前日期
 * @param endDate 结束日期，默认为当前日期
 * @returns 包含所有完整周的数组，每个元素是一个对象，包含开始日期和结束日期
 */
const getWeeksBetweenDates = (startDate: string | Date | { date: string | Date }, endDate: string | Date | { date: string | Date }) => {
  return getWeeksBetweenDates2(startDate, endDate)

  // const weeksTemp = [];

  // // 辅助函数：将输入转换为 Date 对象
  // const convertToDate = (date: string | Date | { date: string | Date }): Date => {
  //   if (date instanceof Date) {
  //     return date;
  //   } else if (typeof date === 'string') {
  //     return new Date(date);
  //   } else if (typeof date === 'object' && date && 'date' in date) {
  //     return new Date(date.date);
  //   } else {
  //     throw new Error('Invalid date format');
  //   }
  // };

  // // 转换开始日期和结束日期
  // const start = convertToDate(startDate);
  // const end = convertToDate(endDate);

  // // 检查 startDate 和 endDate 是否是同一天
  // if (start.toDateString() === end.toDateString()) {
  //   // 计算当前周的第一天（周一）
  //   const weekStart = new Date(start);
  //   weekStart.setDate(start.getDate() - start.getDay());

  //   // 计算当前周的最后一天（周日）
  //   const weekEnd = new Date(weekStart);
  //   weekEnd.setDate(weekStart.getDate() + 6);

  //   // 返回当前周的第一天和最后一天
  //   weeksTemp.push({ start: weekStart, end: weekEnd });
  //   return weeksTemp;
  // }

  // let currentDate = new Date(start);
  // while (currentDate <= end) {
  //   const weekStart = new Date(currentDate);
  //   weekStart.setDate(currentDate.getDate() - currentDate.getDay());
  //   const weekEnd = new Date(weekStart);
  //   weekEnd.setDate(weekStart.getDate() + 6);
  //   if (weekEnd > start && weekStart < end) {
  //     weeksTemp.push({ start: weekStart, end: weekEnd });
  //   }
  //   currentDate = new Date(weekEnd.getTime() + 24 * 60 * 60 * 1000);
  // }
  // return weeksTemp;
};

/**
 * 获取两个日期之间的所有完整周(将星期一作为每周的第一天。星期日作为每周最后一天。)
 *
 * @param startDate 开始日期，默认为当前日期
 * @param endDate 结束日期，默认为当前日期
 * @returns 包含所有完整周的数组，每个元素是一个对象，包含开始日期和结束日期
 */
const getWeeksBetweenDates2 = (startDate: string | Date | { date: string | Date }, endDate: string | Date | { date: string | Date }) => {
  const weeksTemp: any[] = [];

  // 辅助函数：将输入转换为 Date 对象
  const convertToDate = (date: string | Date | { date: string | Date }): Date => {
    if (date instanceof Date) {
      return date;
    } else if (typeof date === 'string') {
      return new Date(date);
    } else if (typeof date === 'object' && date && 'date' in date) {
      return new Date(date.date);
    } else {
      throw new Error('Invalid date format');
    }
  };

  // 转换开始日期和结束日期
  const start = convertToDate(startDate);
  const end = convertToDate(endDate);

  // 如果 start 大于 end，直接返回空数组
  if (start > end) {
    return weeksTemp;
  }

  // 计算 start 所在的周的第一天（周一）
  const startWeekStart = new Date(start);
  startWeekStart.setDate(start.getDate() - (start.getDay() === 0 ? 6 : start.getDay() - 1));

  // 如果 start 不是周的第一天，则从下一周开始
  let currentDate = new Date(startWeekStart);

  while (currentDate <= end) {
    // 计算当前周的第一天（周一）
    const weekStart = new Date(currentDate);
    weekStart.setDate(currentDate.getDate() - (currentDate.getDay() === 0 ? 6 : currentDate.getDay() - 1));

    // 计算当前周的最后一天（周日）
    const weekEnd = new Date(weekStart);
    weekEnd.setDate(weekStart.getDate() + 6);

    // 如果当前周的开始日期在结束日期之前，添加到结果中
    if (weekStart <= end) {
      weeksTemp.push({ start: weekStart, end: weekEnd });
    }

    // 移动到下一周的第一天（周一）
    currentDate = new Date(weekEnd.getTime() + 24 * 60 * 60 * 1000);
  }

  return weeksTemp;
};
/**
 * 将数字格式化为字符串，保留指定的小数位数。
 *
 * @param num 要格式化的数字。
 * @returns 格式化后的字符串，根据小数位数的不同，可能保留到小数点后两位或三位。
 */
const formatNumber = (num: number, decimalPlaces = 3) => {
  if (num === 0) return 0;
  const numStr: any = num.toFixed(decimalPlaces);
  // if (numStr.endsWith('0')) {
  //   numStr = numStr.slice(0, -1);
  // }
  return numStr * 1;
}

/**
 * 判断第一个日期是否小于或等于第二个日期
 *
 * @param date1 第一个日期对象
 * @param date2 第二个日期对象
 * @returns 如果 date1 > date2，返回 0；date1 < date2，返回 1；date1 == date2，返回 2
 */
const isDateLessThanOrEqual = (date1: Date, date2: Date) => {
  // 将日期字符串转换为 Date 对象
  const dt1 = new Date(date1);
  const dt2 = new Date(date2);

  // 设置时间部分为 00:00:00，以确保比较时只考虑日期部分
  dt1.setHours(0, 0, 0, 0);
  dt2.setHours(0, 0, 0, 0);

  const d1 = dt1.getTime();
  const d2 = dt2.getTime();
  // 比较日期
  let result = 0;
  if (d1 < d2) {
    result = 1;
  } else if (d1 === d2) {
    result = 2;
  }
  return result;
}

/**
 * 计算两个时间字符串之间的时间差（以分钟为单位）
 *
 * @param time1 第一个时间字符串，格式为 "HH:MM"
 * @param time2 第二个时间字符串，格式为 "HH:MM"
 * @returns 返回两个时间之间的分钟差
 */
const getTimePercentage = (time1: string, time2: string): number => {
  const [hour1, minute1] = time1.split(':').map(Number);
  const [hour2, minute2] = time2.split(':').map(Number);

  const totalMinutes = 60;
  const minutesDifference = (hour1 - hour2) * totalMinutes + (minute1 - minute2);
  // const percentage = minutesDifference / totalMinutes
  // console.log('percentage', percentage)
  // console.log('minutesDifference', minutesDifference)

  // return Math.round(percentage * 100) / 100
  return minutesDifference;
}

/**
 * 快捷方式类型枚举
 */
enum shortcutsType {
  本年 = '本年',
  近一月 = '近一月',
  前后半年 = '前后半年',
  本月 = '本月',
  本周 = '本周',
  今天 = '今天',
}

/**
 * 根据传入的快捷方式类型获取对应的日期范围
 *
 * @param type 快捷方式类型
 * @returns 日期范围数组，包含开始日期和结束日期，如果没有找到对应的类型，则返回null
 */
const getDateRangeByDate = (type: shortcutsType, currentDate = new Date()) => {
  return getDateRangeByDate2(type, currentDate)
  // const year = currentDate.getFullYear();
  // const month = currentDate.getMonth();
  // const dayOfWeek = currentDate.getDay();
  // let start, end;
  // switch (type) {
  //   case shortcutsType.本月:
  //     start = new Date(year, month, 1);
  //     end = new Date(year, month + 1, 0);
  //     break;
  //   case shortcutsType.本周:
  //     start = new Date(currentDate.getTime() - dayOfWeek * 24 * 60 * 60 * 1000);
  //     end = new Date(start.getTime() + 6 * 24 * 60 * 60 * 1000);
  //     break;
  //   case shortcutsType.近一月:
  //     start = new Date(currentDate.getTime() - 30 * 24 * 60 * 60 * 1000);
  //     end = currentDate;
  //     break;
  //   case shortcutsType.今天:
  //     end = new Date();
  //     start = new Date();
  //     break;
  //   case shortcutsType.本年:
  //     start = new Date(year, 0, 1);
  //     end = new Date(year, 11, 0);
  //     break;
  //   case shortcutsType.前后半年:
  //     // 计算前面第6个月的日期
  //     const sixMonthsAgoYear = month < 6 ? year - 1 : year;
  //     const sixMonthsAgoMonth = (month + 6) % 12;

  //     // 计算后面第5个月的日期
  //     const fiveMonthsLaterYear = month > 6 ? year + 1 : year;
  //     const fiveMonthsLaterMonth = (month + 5) % 12;

  //     start = new Date(sixMonthsAgoYear, sixMonthsAgoMonth, 1);
  //     end = new Date(fiveMonthsLaterYear, fiveMonthsLaterMonth + 1, 0);
  //     break;
  //   default:
  //     return null;
  // }

  // return [start, end];
};
const getDateRangeByDate2 = (type: shortcutsType, currentDate = new Date()) => {
  const year = currentDate.getFullYear();
  const month = currentDate.getMonth();
  const dayOfWeek = currentDate.getDay();
  let start, end;
  switch (type) {
    case shortcutsType.本月:
      start = new Date(year, month, 1);
      end = new Date(year, month + 1, 0);
      break;
    case shortcutsType.本周:
      // start = new Date(currentDate.getTime() - dayOfWeek * 24 * 60 * 60 * 1000);
      // end = new Date(start.getTime() + 6 * 24 * 60 * 60 * 1000);
      // 计算本周的周一
      start = new Date(currentDate)
      start.setDate(currentDate.getDate() - (dayOfWeek === 0 ? 6 : dayOfWeek - 1))
      // 计算本周的周日
      end = new Date(start)
      end.setDate(start.getDate() + 6)
      break;
    case shortcutsType.近一月:
      start = new Date(currentDate.getTime() - 30 * 24 * 60 * 60 * 1000);
      end = currentDate;
      break;
    case shortcutsType.今天:
      end = new Date();
      start = new Date();
      break;
    case shortcutsType.本年:
      start = new Date(year, 0, 1);
      end = new Date(year, 11, 0);
      break;
    case shortcutsType.前后半年:
      // 计算前面第6个月的日期
      const sixMonthsAgoYear = month < 6 ? year - 1 : year;
      const sixMonthsAgoMonth = (month + 6) % 12;

      // 计算后面第5个月的日期
      const fiveMonthsLaterYear = month > 6 ? year + 1 : year;
      const fiveMonthsLaterMonth = (month + 5) % 12;

      start = new Date(sixMonthsAgoYear, sixMonthsAgoMonth, 1);
      end = new Date(fiveMonthsLaterYear, fiveMonthsLaterMonth + 1, 0);
      break;
    default:
      return null;
  }

  return [start, end];
};

/**
 * 计算两个日期之间的工作日天数
 *
 * @param startDateTime 开始日期时间（字符串格式，如 "HH:MM"）
 * @param endDateTime 结束日期时间（字符串格式，如 "HH:MM"）
 * @param workStartTime 上班时间（字符串格式，如 "HH:MM"）
 * @param workEndTime 下班时间（字符串格式，如 "HH:MM"）
 * @param lunchStartTime 午休开始时间（字符串格式，如 "HH:MM"）
 * @param lunchEndTime 午休结束时间（字符串格式，如 "HH:MM"）
 * @returns 返回工作日天数（小数表示部分工作日）
 */
function calculateWorkingDays(startDateTime: any, endDateTime: any, workStartTime: any, workEndTime: any, lunchStartTime: any, lunchEndTime: any) {

  // 将时间字符串转换为时间戳（秒）
  const convertToTimeStamp = (time: any) => {
    const [hours, minutes] = time.split(':').map(Number);
    return hours * 3600 + minutes * 60;
  }
  // 将传入的时间字符串转换为 Date 对象
  const start = new Date(startDateTime);
  const end = new Date(endDateTime);

  // 处理上班、下班、午休时间，将其转换为时间戳
  const workStart = convertToTimeStamp(workStartTime);
  const workEnd = convertToTimeStamp(workEndTime);
  const lunchStart = convertToTimeStamp(lunchStartTime);
  const lunchEnd = convertToTimeStamp(lunchEndTime);

  // 初始化总天数
  let totalDays = 0;

  // 处理开始日期
  const startDay = new Date(start.getFullYear(), start.getMonth(), start.getDate());
  const startDayTime = convertToTimeStamp(`${start.getHours()}:${String(start.getMinutes()).padStart(2, '0')}`);
  if (startDayTime === workStart) {
    totalDays += 1;
  } else if (startDayTime === lunchEnd) {
    totalDays += 0.5;
  } else {
    if (startDayTime >= workStart && startDayTime < lunchStart) {
      totalDays += (lunchStart - startDayTime) / (workEnd - workStart);
    }
    if (startDayTime >= lunchEnd) {
      totalDays += (workEnd - startDayTime) / (workEnd - workStart);
    }
  }

  // 处理结束日期
  const endDay = new Date(end.getFullYear(), end.getMonth(), end.getDate());
  const endDayTime = convertToTimeStamp(`${end.getHours()}:${String(end.getMinutes()).padStart(2, '0')}`);
  if (endDayTime === workEnd) {
    totalDays += 1;
  } else if (endDayTime === lunchStart) {
    totalDays += 0.5;
  } else {
    if (endDayTime >= workStart && endDayTime < lunchStart) {
      totalDays += (endDayTime - workStart) / (workEnd - workStart);
    } else if (endDayTime >= lunchEnd) {
      totalDays += (workStart - lunchStart) / (workEnd - workStart);
      totalDays += (endDayTime - lunchEnd) / (workEnd - workStart);
    }
  }

  // 处理中间的完整工作日
  const current = new Date(startDay.getTime() + 24 * 60 * 60 * 1000);
  while (current < endDay) {
    totalDays += 1;
    current.setDate(current.getDate() + 1);
  }

  return totalDays;
}

/**
 * 统计给定时间范围内周六、周日的数量以及根据legalData调整的总天数
 *
 * @param startTime 起始时间的字符串表示，格式为 YYYY-MM-DD
 * @param endTime 结束时间的字符串表示，格式为 YYYY-MM-DD
 * @param legalData 合法日期数组，每项包含 legalDate（日期字符串，格式为 YYYY-MM-DD）和 legalType（类型，1 表示增加天数，2 表示减少天数）
 * @returns 包含周六、周日总数、legalType 调整值及最终总天数的对象
 */
function countWeekendAndLegalDays(startTime: any, endTime: any, legalData: any[] = []) {
  let weekendCount = 0; // 统计周六、周日的数量
  let legalAdjustment = 0; // 统计 legalType 的调整值

  // 将日期字符串转换为 Date 对象
  const startDate = new Date(startTime);
  const endDate = new Date(endTime);

  // 遍历日期范围内的每一天
  for (let date = startDate; date <= endDate; date.setDate(date.getDate() + 1)) {
    const dayOfWeek = date.getDay(); // 获取当前日期是周几（0：周日，6：周六）
    const dateStr = date.toISOString().split('T')[0]; // 将日期转换为 YYYY-MM-DD 格式

    // 判断是否是周六或周日
    if (dayOfWeek === 0 || dayOfWeek === 6) {
      weekendCount++;
    }

    // 检查当前日期是否在 legalData 中
    const legalItem = legalData.find(item => item.legalDate === dateStr);
    if (legalItem) {
      if (legalItem.legalType === 1) {
        legalAdjustment++; // legalType 为 1，增加 1
        if (dayOfWeek === 0 || dayOfWeek === 6) {
          legalAdjustment--; // 如果是周六或周日，减少 1
        }
      } else if (legalItem.legalType === 2) {
        legalAdjustment--; // legalType 为 2，减少 1
      }
    }
  }

  return {
    weekendCount, // 周六、周日的总数
    legalAdjustment, // legalType 的调整值
    total: weekendCount + legalAdjustment, // 最终的总数
  };
}

/**
 * 获取指定时间范围内的工作日日期列表
 *
 * @param startTime 开始时间
 * @param endTime 结束时间
 * @param startLunchTime 午餐开始时间，格式为HH:mm
 * @param endLunchTime 午餐结束时间，格式为HH:mm
 * @param legalData 法定节假日信息数组，默认为空数组
 * @returns 返回包含工作日日期及工作时长（0.5表示半天，1表示整天）的对象数组
 */
function getWorkdayDates(startTime: any, endTime: any, startLunchTime: any, endLunchTime: any, legalData: any[] = []) {

  // 参数处理
  const startDate = new Date(startTime);
  const endDate = new Date(endTime);
  const legalMap = legalData
    .filter(item => item.legalType == 1 || item.legalType == 2)
    .reduce((acc, item) => {
      acc[item.legalDate] = item.legalType;
      return acc;
    }, {});
  // 生成日期范围
  const dates = [];
  const current = new Date(startDate);
  current.setHours(0, 0, 0, 0);
  endDate.setHours(23, 59, 59, 999);

  while (current <= endDate) {
    dates.push(new Date(current));
    current.setDate(current.getDate() + 1);
  }

  // 判断工作日逻辑
  const result = dates.filter(date => {
    const dateStr = formatDate(date, 'yyyy-MM-dd');
    const dayOfWeek = date.getDay();

    // 默认工作日：周一到周五
    let isWorkday = dayOfWeek >= 1 && dayOfWeek <= 5;

    // 法定日期覆盖
    if (legalMap[dateStr] === 1) isWorkday = false;
    if (legalMap[dateStr] === 2) isWorkday = true;

    return isWorkday;
  }).map(date => ({
    num: 1,  // 根据示例需求始终返回整天
    leaveDate: formatDate(date, 'yyyy-MM-dd')
  }));
  if (result && result.length) {
    if (formatDate(new Date(startTime), 'HH:mm') == endLunchTime) {
      result[0].num = 0.5
    }
    if (formatDate(new Date(endTime), 'HH:mm') == startLunchTime) {
      result[result.length - 1].num = 0.5
    }
  }
  return result;
}
function getMinutesDifference(startTime: Date, endTime: Date) {
  const startDate = new Date(startTime);
  const endDate = new Date(endTime);
  // 如果结束时间早于开始时间，说明跨天
  if (endDate < startDate) {
    endDate.setDate(endDate.getDate() + 1); // 结束时间加一天
  }

  const timeDifference = endDate.getTime() - startDate.getTime();
  const minutesDifference = Math.floor(timeDifference / (1000 * 60));

  return minutesDifference;
}

/**
 * 计算一个日期时间加上额外分钟后的时间，并返回包含日期和时间的字符串
 * @param {Date} dateTime - 原始日期时间对象
 * @param {number} minutes - 需要添加的分钟数
 * @returns {string} 返回计算后的日期时间字符串，格式为 "YYYY-MM-DD HH:MM"
 */
function addMinutesToDateTime(dateTime: Date, minutes: number) {
  // 创建一个新的 Date 对象以避免修改原始对象
  const newDateTime = new Date(dateTime);

  // 添加分钟数
  newDateTime.setMinutes(newDateTime.getMinutes() + minutes);

  // 返回格式化的日期时间字符串
  return formatDate(newDateTime, 'yyyy-MM-dd HH:mm')
}
/**
 * 判断两个日期是否属于同一周
 *
 * @param date1 第一个日期，类型为Date对象或可转换为Date对象的字符串
 * @param date2 第二个日期，类型为Date对象或可转换为Date对象的字符串
 * @returns 如果两个日期属于同一周，则返回true；否则返回false
 */
function isSameWeek(date1: any, date2: any) {
  // 确保输入是Date对象
  const d1 = new Date(date1);
  const d2 = new Date(date2);

  // 计算每个日期所在周的第一天（周一）
  const getWeekStart = (date: Date) => {
    const day = date.getDay() || 7; // 0是周日，转换为7
    const diff = date.getDate() - day + 1; // 调整到周一
    return new Date(date.setDate(diff));
  };

  // 获取两个日期的周一开始日期
  const weekStart1 = getWeekStart(new Date(d1));
  const weekStart2 = getWeekStart(new Date(d2));

  // 比较年、月、日是否相同
  return weekStart1.getFullYear() === weekStart2.getFullYear() &&
    weekStart1.getMonth() === weekStart2.getMonth() &&
    weekStart1.getDate() === weekStart2.getDate();
}
/**
 * 判断date1是否小于等于date2
 * @param {Date|string} date1 - 第一个日期
 * @param {Date|string} date2 - 第二个日期
 * @returns {boolean} - 如果date1 <= date2返回true，否则false
 */
function isDateLessOrEqual(date1: any, date2: any) {
  // 转换为Date对象
  const d1 = new Date(date1);
  const d2 = new Date(date2);

  // 比较时间戳
  return d1.getTime() <= d2.getTime();
}

function getWeekEnd(date: Date) {
  const day = date.getDay()
  const diff = date.getDate() - day + (day === 0 ? 0 : 7) // 如果是周日，不调整
  return new Date(date.setDate(diff))
}
/**
* 返回指定月数前的日期
*
* @param date 基准日期，默认为当前日期
* @param ago 要回溯的月数，默认为3个月
* @returns 返回指定月数前的日期
*/
function getMonthsAgo(date = new Date(), ago = 3) {
  const currentDate = date;
  currentDate.setMonth(currentDate.getMonth() - ago);
  return currentDate;
}
export {
  getWeekEnd,
  isDateLessOrEqual,
  isSameWeek,
  storage,
  userRole,
  ResultMessage,
  formatDate,
  generateDates,
  generateDates2,
  isDateBetween,
  getTodayAndPreviousTwoWeeks,
  getWeeksBetweenDates,
  getWeeksBetweenDates2,
  isDateLessThanOrEqual,
  getTimePercentage,
  formatNumber,
  getDateRangeByDate,
  getDateRangeByDate2,
  shortcutsType,
  calculateWorkingDays,
  countWeekendAndLegalDays,
  getWorkdayDates,
  getMinutesDifference,
  addMinutesToDateTime,
  getMonthsAgo,
};
